#include "kernel/types.h"
#include "kernel/stat.h"
#include "kernel/fcntl.h"
#include "user/user.h"
#include "kernel/fs.h"
#include "kernel/param.h"

#define ARGLEN 16

// keypointer: construct a array of string as argv of exec syscall

int
fexec(char * cmd, char **argv)
{
  int pid = fork();
  if(pid == 0){
    exec(cmd, argv);
  }else if(pid > 0){
    wait(0);
  }else{
    fprintf(2, "xargs: fork fail\n");
    exit(1);
  }
  return 0;
}

int
main(int argc, char *argv[])
{
  // argv test
  // int i; 
  // for(i=0; i<argc; i++)
  //   printf("length per argv array %p is %d \n", argv[i], strlen(argv[i]));

  // pipe test
  // char buf[128];
  // char *p = buf;
  // int rt;
  // while(read(0, p, 1)){
  //   p++;
  // }

  char * xargs[MAXARG];
  int xargc = 0;
  char buf[MAXARG][ARGLEN];
  memset(buf, 0, MAXARG*ARGLEN);
  // refer to sh.c
  char * whitespace = " \t\r\n\v";
  if(argc == 1){
    strcpy(buf[0], "echo");
    xargc++;
  }
  while(xargc < argc-1){
    strcpy(buf[xargc], argv[xargc+1]);
    xargc++;
  }
  // struct stat st;
  // if(fstat(0, &st) != 0){
  //   fprintf(2, "xargs: cannot stat stdin\n");
  //   exit(1);
  // }
  int i = 0;
  int j;
  for(j=0; j<=xargc; j++)
    xargs[j] = buf[j];
  // when stdin have not any input, read blocked
  while(read(0, buf[xargc]+i, 1) == 1){
    // printf("dbg: get %c from stdin\n", *(buf[xargc]+i));
    if(strchr(whitespace, *(buf[xargc]+i))){
      // unit end char of string
      *(buf[xargc]+i) = '\0';
      fexec(xargs[0], xargs);
      i=0;
    }else{
      i++;
    }
    // TODO: handle too long arg
  }
  exit(0);
}
